﻿Imports RSToolKit.ReportService
Imports System.Xml

Public Class ReportInfo

    Private _Generic As DataTable
    Private _Security As DataTable
    Private _DataSource As DataTable
    Private _Queries As DataTable
    Private _Fields As DataTable
    Private _CI As CatalogItem
    Private _Path As String = Nothing
    Private _Server As ReportServer
    Private oDoc As System.Xml.XmlDocument

    Public ReadOnly Property ReportServerURL() As String
        Get
            Return _Server.URL.ToString()
        End Get
    End Property

    Public ReadOnly Property ReportServerURI() As Uri
        Get
            Return _Server.URI
        End Get
    End Property

    Public ReadOnly Property Name() As String
        Get
            Return _CI.Name.ToString()
        End Get
    End Property

    Public ReadOnly Property Path() As String
        Get
            Return _CI.Path.ToString()
        End Get
    End Property

    Public ReadOnly Property ReportID() As String
        Get
            Return _CI.ID.ToString
        End Get
    End Property

    Public ReadOnly Property CreationDate() As Date
        Get
            Return _CI.CreationDate
        End Get
    End Property

    Public ReadOnly Property ModifiedDate() As Date
        Get
            Return _CI.ModifiedDate
        End Get
    End Property

    Public ReadOnly Property CreationBy() As String
        Get
            Return _CI.CreatedBy
        End Get
    End Property

    Public ReadOnly Property ModifiedBy() As String
        Get
            Return _CI.ModifiedBy
        End Get
    End Property

    Public Sub New(ByVal Server As ReportServer, ByVal CatalogItem As CatalogItem)
        _Server = Server
        _Path = CatalogItem.Path
        _CI = CatalogItem

        _Generic = New DataTable("Generic")
        _Generic.Columns.Add("ID", System.Type.GetType("System.String"))
        _Generic.Columns.Add("Path", System.Type.GetType("System.String"))
        _Generic.Columns.Add("CreatedBy", System.Type.GetType("System.String"))
        _Generic.Columns.Add("CreatedAt", System.Type.GetType("System.String"))
        _Generic.Columns.Add("ModifiedBy", System.Type.GetType("System.String"))
        _Generic.Columns.Add("ModifiedAt", System.Type.GetType("System.String"))

        _Security = New DataTable("Security")
        _Security.Columns.Add("Username", System.Type.GetType("System.String"))
        _Security.Columns.Add("Role", System.Type.GetType("System.String"))

        _DataSource = New DataTable("DataSources")
        _DataSource.Columns.Add("Name", System.Type.GetType("System.String"))
        _DataSource.Columns.Add("DataProvider", System.Type.GetType("System.String"))
        _DataSource.Columns.Add("ConnectionString", System.Type.GetType("System.String"))

        _Queries = New DataTable("Queries")
        _Queries.Columns.Add("DataSet", System.Type.GetType("System.String"))
        _Queries.Columns.Add("DataSourceName", System.Type.GetType("System.String"))
        _Queries.Columns.Add("CommandText", System.Type.GetType("System.String"))

        _Fields = New DataTable("Fields")
        _Fields.Columns.Add("DataSet", System.Type.GetType("System.String"))
        _Fields.Columns.Add("DataSource", System.Type.GetType("System.String"))
        _Fields.Columns.Add("Schema", System.Type.GetType("System.String"))
        _Fields.Columns.Add("ColumnOwner", System.Type.GetType("System.String"))
        _Fields.Columns.Add("ColumnName", System.Type.GetType("System.String"))
        _Fields.Columns.Add("TypeName", System.Type.GetType("System.String"))

        Try
            LoadRDL(Server.ws.GetReportDefinition(CatalogItem.Path))
        Catch ex As Exception

        End Try
    End Sub

    Public Function GetGenericDataTable() As DataTable
        _Generic.Rows.Clear()
        Dim row As DataRow = _Generic.NewRow
        row("ID") = _CI.ID
        row("Path") = _CI.Path
        row("CreatedBy") = _CI.CreatedBy
        row("CreatedAt") = _CI.CreationDate
        row("ModifiedBy") = _CI.ModifiedBy
        row("ModifiedAt") = _CI.ModifiedDate
        _Generic.Rows.Add(row)
        Return _Generic
    End Function

    Public Function GetSecurityDataTable() As DataTable
        Dim Policies() As RSToolKit.ReportService.Policy = _Server.ws.GetPolicies(_Path, True)
        _Security.Rows.Clear()
        For i As Integer = 0 To Policies.Length - 1
            Dim row As DataRow = _Security.NewRow
            row(0) = Policies(i).GroupUserName.ToString
            Dim strRole As String = Nothing
            For Each role As RSToolKit.ReportService.Role In Policies(i).Roles
                strRole += role.Name.ToString() + ", "
            Next
            row(1) = strRole.Substring(0, strRole.Length - 2)
            _Security.Rows.Add(row)
        Next
        Return _Security
    End Function

    Public Function GetDataSourcesDataTable() As DataTable
        Dim reader As XmlNodeReader = New XmlNodeReader(oDoc)
        _DataSource.Rows.Clear()
        Dim row As DataRow
        While reader.Read
            Select Case reader.NodeType
                Case XmlNodeType.Element
                    If reader.Name = "DataSource" Then
                        row = _DataSource.NewRow
                        row(0) = reader("Name").ToString
                    End If
                    If reader.Name = "DataProvider" Then
                        row(1) = reader.ReadInnerXml
                    End If
                    If reader.Name = "ConnectString" Then
                        row(2) = reader.ReadInnerXml
                        _DataSource.Rows.Add(row)
                    End If
            End Select
        End While
        Return _DataSource
    End Function

    Public Function GetQueriesDataTable() As DataTable
        Dim reader As XmlNodeReader = New XmlNodeReader(oDoc)
        _Queries.Rows.Clear()
        Dim row As DataRow
        While reader.Read
            Select Case reader.NodeType
                Case XmlNodeType.Element
                    If reader.Name = "DataSet" Then
                        row = _Queries.NewRow
                        row("DataSet") = reader("Name")
                    End If
                    If reader.Name = "DataSourceName" Then
                        row("DataSourceName") = reader.ReadInnerXml
                    End If
                    If reader.Name = "CommandText" Then
                        row("CommandText") = reader.ReadInnerXml
                        _Queries.Rows.Add(row)
                    End If
            End Select
        End While
        Return _Queries
    End Function

    Public Function GetFieldsDataTable() As DataTable
        Try
            Dim reader As XmlNodeReader = New XmlNodeReader(oDoc)
            _Fields.Rows.Clear()
            Dim row As DataRow
            Dim rDataSet As String = Nothing
            Dim rDataSource As String = Nothing
            Dim rField As String = Nothing
            Dim bColumnExpression As Boolean = False
            While reader.Read
                Select Case reader.NodeType
                    Case XmlNodeType.Element

                        If reader.Name = "DataSet" Then
                            rDataSet = reader("Name").ToString
                            bColumnExpression = False
                        End If

                        If reader.Name = "DataSourceName" Then
                            rDataSource = reader.ReadInnerXml.ToString
                        End If

                        If reader.Name = "ColumnExpression" Then
                            bColumnExpression = True
                            row = _Fields.NewRow
                            row("DataSet") = rDataSet
                            row("DataSource") = rDataSource
                            row("Schema") = reader("Schema").ToString
                            row("ColumnOwner") = reader("ColumnOwner").ToString
                            row("ColumnName") = reader("ColumnName").ToString
                            _Fields.Rows.Add(row)
                        End If

                        If reader.Name = "DataField" Then
                            rField = reader.ReadInnerXml.ToString()
                            If bColumnExpression = False Then
                                row = _Fields.NewRow
                                row("DataSet") = rDataSet
                                row("DataSource") = rDataSource
                                row("ColumnName") = rField
                                _Fields.Rows.Add(row)
                            End If
                        End If

                        If reader.Name = "rd:TypeName" Then
                            Dim Expression As String = "DataSet = '" + rDataSet + "' AND ColumnName = '" + rField + "'"
                            Dim frow As DataRow() = _Fields.Select(Expression)
                            If frow.Length = 1 Then
                                frow(0)("TypeName") = reader.ReadInnerXml.ToString()
                            End If
                        End If
                End Select
            End While
        Catch ex As Exception
        End Try
        Return _Fields
    End Function

    Public Sub LoadRDL(ByVal Report As Byte())
        Dim oByteStream As System.IO.MemoryStream = New System.IO.MemoryStream(Report)
        Dim oRD As System.Xml.XmlTextReader = New System.Xml.XmlTextReader(oByteStream)
        oDoc = New System.Xml.XmlDocument()
        oDoc.Load(oRD)
    End Sub

End Class